#pragma once
#include "Acceptor.h"
#include "Buffer.h"
#include "Callbacks.h"
#include "EventLoop.h"
#include "EventLoopThreadPool.h"
#include "InetAddress.h"
#include "Noncopyable.h"
#include "Poller.h"
#include "Socket.h"
#include "TcpConnection.h"
#include <functional>
#include <unordered_map>

class TcpServer : Noncopyable
{
  public:
    using ThreadInitCallback = std::function<void(EventLoop *)>;

    enum OPTION
    {
        NO_REUSE_PORT,
        REUSE_PORT
    };

  private:
    using ConnectionMap = std::unordered_map<std::string, TcpConnectionPtr>;

    EventLoop *loop_;
    const std::string ipPort_;
    const std::string name_;
    std::unique_ptr<Acceptor> acceptor_; // 运行在mainLoop，任务是监听新连接事件
    std::shared_ptr<EventLoopThreadPool> threadPool_;

    ConnectionCallback connectionCallback_;       // 有新连接时的回调
    MessageCallback messageCallback_;             // 有新消息时的回调
    WriteCompleteCallback writeCompleteCallback_; // 写完成时的回调

    ThreadInitCallback threadInitCallback_; // loop 线程初始化的回调
    std::atomic_int started_;
    int nextConnId_;
    ConnectionMap connections_; // 保存所有的连接

  public:
    TcpServer(EventLoop *loop, const InetAddress &listenAddr,
              const std::string &nameArg, OPTION option = NO_REUSE_PORT);
    ~TcpServer();
    void setThreadNum(int numThreads); // 设置subLoop的个数
    void setThreadInitCallback(const ThreadInitCallback &cb)
    {
        threadInitCallback_ = cb;
    }
    void setConnectionCallback(const ConnectionCallback &cb)
    {
        connectionCallback_ = cb;
    }
    void setMessageCallback(const MessageCallback &cb)
    {
        messageCallback_ = cb;
    }
    void setWriteCompleteCallback(const WriteCompleteCallback &cb)
    {
        writeCompleteCallback_ = cb;
    }
    void start(); // 开启服务器监听
  private:
    void newConnection(int sockfd, const InetAddress &peerAddr);
    void removeConnection(const TcpConnectionPtr &conn);
    void removeConnectionInLoop(const TcpConnectionPtr &conn);

}; // class TcpServer
